"""
    Properties used to access variables and functions in GAME.DLL
    No real work is done here, this just passes calls to a Stack object.
"""

class CallProp(object):
    'Descriptor for (unbound) functions. Returns a CallProxy (that is bound do a Stack instance) when accessed.'

    def __init__(self,name):
        self.name=name

    def __get__(self,instance,owner):
        if instance is None: return self
        return CallProxy(instance.stack,self.name)

    def __repr__(self):
        return '<Unbound %s: %s>'%(type(self).__name__,self.name)

class QueryProp(CallProp):
    'Descriptor for (unbound) queries. Returns a QueryProxy.'

    def __get__(self,instance,owner):
        if instance is None: return self
        return QueryProxy(instance.stack,self.name)

class CallProxy(object):
    'Perform an actual call to GAME.DLL when called.'

    def __init__(self,stack,name):
        self.stack=stack
        self.name=name

    def __call__(self,*a):
        return self.stack.Execute(self.name,*a)

    def __repr__(self):
        return '<%s: %s for stack 0x%08x>'%(type(self).__name__,self.name,self.stack.hnd)

class QueryProxy(CallProxy):
    'Perform an actual Query to GAME.DLL when called.'

    def __call__(self,*a):
        return self.stack.Query(self.name,*a)


class RVarProp(property):
    'ReadOnly property descriptor, performs a GetVar() call when accessed.'

    def __init__(self,name):
        self.name=name

    def __get__(self,instance,owner):
        if instance is None: return self
        return instance.stack.Query('GetVar',self.name)

    def __set__(self,instance,value):
        raise AttributeError('%s is read-only.'%self.name)

    def __repr__(self):
        return '<%s: %s>'%(type(self).__name__,self.name)

class WVarProp(RVarProp):
    'Read/Write property descriptor, overrides __set__ to call SetVar().'

    def __set__(self,instance,value):
        assert instance is not None
        return instance.stack.Query('SetVar',self.name,value)
